package com.jack006.user.controller;

import com.jack006.api.BaseController;
import com.jack006.api.controller.user.PassportControllerApi;
import com.jack006.enums.UserStatus;
import com.jack006.grace.result.GraceJSONResult;
import com.jack006.grace.result.ResponseStatusEnum;
import com.jack006.pojo.AppUser;
import com.jack006.pojo.bo.RegisterLoginBO;
import com.jack006.user.service.UserService;
import com.jack006.utils.IpUtils;
import com.jack006.utils.JsonUtils;
import com.jack006.utils.SMSUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.UUID;

/**
 * @Classname HelloController
 * @Description 接口实现类
 * @Date 2021-06-10 08:15
 * @Created by jack
 */
@RestController
public class PassportController extends BaseController implements PassportControllerApi {

    final static Logger logger = LoggerFactory.getLogger(PassportController.class);

    @Autowired
    private  SMSUtils smsUtils;
    @Autowired
    private UserService userService;


    @Override
    public GraceJSONResult getSMSCode(String mobile, HttpServletRequest request) {

        String userIp = IpUtils.getRequestIp(request);

        // 根据用户的 Ip 进行限制，限制用户在60 秒内只能获取一次验证码
        redisOperator.setnx60s(MOBILE_SMSCODE+":"+userIp,userIp);

        // 生成随机验证码并且发送短信
        String random = (int)((Math.random()*9+1)*100000)+"";
        // smsUtils.sendSMS(MyInfo.getMobile(),random);

        // 把验证码存入 redis 用于后续进行验证
        redisOperator.set(MOBILE_SMSCODE+":"+mobile,random,30*60);

        logger.info("发送手机："+mobile+"的验证码是"+random);
        return GraceJSONResult.ok();
    }

    @Override
    public GraceJSONResult doLogin(@Valid RegisterLoginBO registerLoginBO,
                                   HttpServletRequest request,
                                   HttpServletResponse response) {

        String mobile = registerLoginBO.getMobile();
        String smsCode = registerLoginBO.getSmsCode();

        // 1、校验验证码是否匹配
        String redisSmsCode = redisOperator.get(MOBILE_SMSCODE + ":" + mobile);
        if (StringUtils.isBlank(redisSmsCode) || !redisSmsCode.equalsIgnoreCase(smsCode)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.SMS_CODE_ERROR);
        }

        // 2、查询数据库，判读用户注册
        AppUser appUser = userService.queryMobileIsExist(mobile);
        if (appUser != null && appUser.getActiveStatus().equals(UserStatus.FROZEN.type)) {
            // 如果用户不为空，并且状态为冻结，则直接抛出异常，禁止登录
            return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_FROZEN);
        } else if (appUser == null) {
            // 如果用户没有注册过，则为 null ，需要注册信息入库
             appUser = userService.createUser(mobile);
        }

        // 3、保存用户分布式会话的相关操作
        int activeStatus = appUser.getActiveStatus();
        if (activeStatus != UserStatus.FROZEN.type) {
            // 保存 token 到 redis
            String uToken = UUID.randomUUID().toString();
            redisOperator.set(REDIS_USER_TOKEN+":"+appUser.getId(),uToken);
            redisOperator.set(REDIS_USER_INFO+":"+appUser.getId(),
                    JsonUtils.objectToJson(appUser));


            // 保存用户 Id 和 token 到 cookie 中
            setCookie(request,response,"utoken",uToken,COOKIE_MONTH);
            setCookie(request,response,"uid",appUser.getId(),COOKIE_MONTH);
        }

        // 4、用户登录或注册以后，需要删除 redis 中的短信验证码，验证码只能使用一次
        redisOperator.del(MOBILE_SMSCODE+":"+mobile);

        // 5、返回用户状态
        return GraceJSONResult.ok(activeStatus);
    }



    @Override
    public GraceJSONResult logout(String userId, HttpServletRequest request, HttpServletResponse response) {

        // 1、redis 删除用户信息
        redisOperator.del(REDIS_USER_TOKEN+":"+userId);

        setCookie(request,response,"utoken","",COOKIE_DELETE);
        setCookie(request,response,"uid","",COOKIE_DELETE);

        return GraceJSONResult.ok();
    }

}
